{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "nbgrader": {
     "grade": false,
     "grade_id": "jupyter",
     "locked": true,
     "solution": false
    }
   },
   "source": [
    "For this problem set, we'll be using the Jupyter notebook:\n",
    "\n",
    "![](jupyter.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbgrader": {
     "grade": false,
     "solution": false
    }
   },
   "source": [
    "---\n",
    "## Part A (2 points)\n",
    "\n",
    "Write a function that returns a list of numbers, such that $x_i=i^2$, for $1\\leq i \\leq n$. Make sure it handles the case where $n<1$ by raising a `ValueError`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "nbgrader": {
     "grade_id": "squares",
     "solution": true
    }
   },
   "outputs": [],
   "source": [
    "def squares(n):\n",
    "    \"\"\"Compute the squares of numbers from 1 to n, such that the \n",
    "    ith element of the returned list equals i^2.\n",
    "    \n",
    "    \"\"\"\n",
    "    ### BEGIN SOLUTION\n",
    "    if n < 1:\n",
    "        raise ValueError(\"n must be greater than or equal to 1\")\n",
    "    return [i ** 2 for i in range(1, n + 1)]\n",
    "    ### END SOLUTION"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbgrader": {
     "grade": false,
     "solution": false
    }
   },
   "source": [
    "Your function should print `[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]` for $n=10$. Check that it does:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "nbgrader": {
     "grade": false,
     "solution": false
    }
   },
   "outputs": [],
   "source": [
    "squares(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "nbgrader": {
     "grade": true,
     "grade_id": "correct_squares",
     "points": "1"
    }
   },
   "outputs": [],
   "source": [
    "\"\"\"Check that squares returns the correct output for several inputs\"\"\"\n",
    "assert squares(1) == [1]\n",
    "assert squares(2) == [1, 4]\n",
    "assert squares(10) == [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]\n",
    "assert squares(11) == [1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "nbgrader": {
     "grade": true,
     "grade_id": "squares_invalid_input",
     "points": "1"
    }
   },
   "outputs": [],
   "source": [
    "\"\"\"Check that squares raises an error for invalid inputs\"\"\"\n",
    "try:\n",
    "    squares(0)\n",
    "except ValueError:\n",
    "    pass\n",
    "else:\n",
    "    raise AssertionError(\"did not raise\")\n",
    "\n",
    "try:\n",
    "    squares(-4)\n",
    "except ValueError:\n",
    "    pass\n",
    "else:\n",
    "    raise AssertionError(\"did not raise\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbgrader": {
     "grade": false,
     "solution": false
    }
   },
   "source": [
    "---\n",
    "\n",
    "## Part B (1 point)\n",
    "\n",
    "Using your `squares` function, write a function that computes the sum of the squares of the numbers from 1 to $n$. Your function should call the `squares` function -- it should NOT reimplement its functionality."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "nbgrader": {
     "grade_id": "sum_of_squares",
     "solution": true
    }
   },
   "outputs": [],
   "source": [
    "def sum_of_squares(n):\n",
    "    \"\"\"Compute the sum of the squares of numbers from 1 to n.\"\"\"\n",
    "    ### BEGIN SOLUTION\n",
    "    return sum(squares(n))\n",
    "    ### END SOLUTION"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbgrader": {
     "grade": false,
     "solution": false
    }
   },
   "source": [
    "The sum of squares from 1 to 10 should be 385. Verify that this is the answer you get:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "nbgrader": {
     "grade": false,
     "solution": false
    }
   },
   "outputs": [],
   "source": [
    "sum_of_squares(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "nbgrader": {
     "grade": true,
     "grade_id": "correct_sum_of_squares",
     "points": 0.5
    }
   },
   "outputs": [],
   "source": [
    "\"\"\"Check that sum_of_squares returns the correct answer for various inputs.\"\"\"\n",
    "assert sum_of_squares(1) == 1\n",
    "assert sum_of_squares(2) == 5\n",
    "assert sum_of_squares(10) == 385\n",
    "assert sum_of_squares(11) == 506"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "nbgrader": {
     "grade": true,
     "grade_id": "sum_of_squares_uses_squares",
     "points": 0.5
    }
   },
   "outputs": [],
   "source": [
    "\"\"\"Check that sum_of_squares relies on squares.\"\"\"\n",
    "orig_squares = squares\n",
    "del squares\n",
    "try:\n",
    "    sum_of_squares(1)\n",
    "except NameError:\n",
    "    pass\n",
    "else:\n",
    "    raise AssertionError(\"sum_of_squares does not use squares\")\n",
    "finally:\n",
    "    squares = orig_squares"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbgrader": {
     "grade": false,
     "solution": false
    }
   },
   "source": [
    "---\n",
    "## Part C (1 point)\n",
    "\n",
    "Using LaTeX math notation, write out the equation that is implemented by your `sum_of_squares` function."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbgrader": {
     "grade": true,
     "grade_id": "sum_of_squares_equation",
     "points": "1",
     "solution": true
    }
   },
   "source": [
    "$\\sum_{i=1}^n i^2$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbgrader": {
     "grade": false,
     "solution": false
    }
   },
   "source": [
    "---\n",
    "## Part D (2 points)\n",
    "\n",
    "Find a usecase for your `sum_of_squares` function and implement that usecase in the cell below."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true,
    "nbgrader": {
     "grade": true,
     "points": 2,
     "solution": true
    }
   },
   "outputs": [],
   "source": [
    "def pyramidal_number(n):\n",
    "    \"\"\"Returns the n^th pyramidal number\"\"\"\n",
    "    return sum_of_squares(n)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python",
   "language": "python",
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
